#include "SocketIO.h"
#include <cerrno>

SocketIO::SocketIO(int fd)
    : _fd(fd)
{
}

int SocketIO::readn(char *buf, int len)
{
    int left = len;
    char *pbuf = buf;
    while(left > 0){
        int ret = ::recv(_fd,pbuf,left,0);
        if(ret == -1 &&  errno == EINTR){
            continue;
        }else if(ret == -1){
            perror("recv");
        }else if(ret == 0){
            return len - left;
        }else{
            left -= ret;
            pbuf += ret;
        }
    }
    return len;
}
int SocketIO::sendn(const char *buf, int len)
{
    int left = len;
    const char * pbuf = buf;
    while(left > 0){
        int ret = ::send(_fd,pbuf,left,0);
        if(ret < 0){
            perror("send");
            return ret;
        }else{
            left -= ret;
            pbuf += ret;
        }
    }
    return len;
}
int SocketIO::readline(char *buf, int maxlen)
{
    //读取整行数据以'\n'为分界点
    int left = maxlen - 1;
    char *pbuf = buf;
    int total = 0;//统计总共读到多少
    while(left > 0){
        int ret = recvPeek(pbuf,left);
        for(int i =0; i < ret; ++i){
            if(pbuf[i] == '\n'){
                //找到'\n'分界点
                int size = i + 1;
                ret = readn(pbuf,size);
                total += ret;
                pbuf[i] = '\0';
                return total;
            }
        }
        //读取peek到的数据
        ret = readn(pbuf,ret);
        left -= ret;
        pbuf += ret;
        total += ret;
    }
    buf[maxlen - 1] = '\0';
    return total;
}
int SocketIO::recvPeek(char *buf, int maxlen)
{
    int ret = 0;
    do{
        ret = recv(_fd,buf,maxlen,MSG_PEEK);
    }while(ret == -1 && errno == EINTR);
    if(ret < 0){
        perror("recv");
    }
    return ret;
}
